package com.wawei.seeds.champion;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.HeaderViewListAdapter;

import com.wawei.seeds.R;
import com.wawei.seeds.adapter.ChampionAchievementFragmentAdapter;
import com.wawei.seeds.services.AchievementServiceHandler;
import com.wawei.seeds.utils.PrefUtils;
import com.wawei.seeds.utils.PullupToMoreListView;
import com.wawei.seeds.utils.RetrofitNetworkService;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;

import butterknife.ButterKnife;
import butterknife.InjectView;
import retrofit.RestAdapter;
import uk.co.senab.actionbarpulltorefresh.library.ActionBarPullToRefresh;
import uk.co.senab.actionbarpulltorefresh.library.PullToRefreshLayout;
import uk.co.senab.actionbarpulltorefresh.library.listeners.OnRefreshListener;

/**
 * Created by parker on 15/6/7.
 */
public class ChampionAchievementTabFragment extends Fragment implements OnRefreshListener, AbsListView.OnScrollListener {
    private static final String TAG = "ChampionAchievementTabFragment";

    @InjectView(R.id.achievementPullRefresh) PullToRefreshLayout pullToRefreshLayout;
    @InjectView(R.id.achievementList) PullupToMoreListView achievmentList;

    //Async operation (get achievement data etc.)
    private NotifyHandler notifyHandler;
    public static final int LOAD_NEW_ACHIEVE_DATA = 0x01;
    public static final int LOAD_OLD_ACHIEVE_DATA = 0x02;
    public static final int INIT_ACHIEVE_DATA = 0x03;

    //List adapter
    private ChampionAchievementFragmentAdapter adapter;
    //Recording the position of current showing items
    private int currentFirstShowingItem = -1;

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
    }

    @Override
    public void onDetach() {
        super.onDetach();
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if(null == notifyHandler){
            notifyHandler = new NotifyHandler(this);
        }
        else {
            notifyHandler.setTarget(this);
        }
        initAchievementListDataset();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.tab_champion_achievement, null, false);
        ButterKnife.inject(this, view);

        initAchievementList();

        return view;
    }

    @Override
    public void onResume() {
        super.onResume();
        currentFirstShowingItem = PrefUtils.getFirstShowingItem(getActivity(), TAG);
    }

    @Override
    public void onPause() {
        PrefUtils.markFirstShowingItem(getActivity(), TAG, currentFirstShowingItem);
        super.onPause();
    }

    private void initAchievementList(){
        ActionBarPullToRefresh.from(getActivity())
                .theseChildrenArePullable(R.id.achievementList)
                .listener(this)
                .setup(pullToRefreshLayout);

        achievmentList.setOnLoadMoreListener(new PullupToMoreListView.OnLoadMoreListener() {
            @Override
            public void onLoadMore() {
                AchievementServiceHandler serviceHandler = new AchievementServiceHandler(getActivity());
                RestAdapter adapter = RetrofitNetworkService.makeAsyncRestAdapter();
                serviceHandler.retriveAchievement(adapter, 0, notifyHandler, LOAD_OLD_ACHIEVE_DATA);
            }
        });

        achievmentList.setOnScrollListener(this);

        if(null != adapter){
            achievmentList.setAdapter(adapter);
        }

        if(currentFirstShowingItem > -1){
            achievmentList.setSelection(currentFirstShowingItem);
        }
    }

    @Override
    public void onRefreshStarted(View view) {
        AchievementServiceHandler serviceHandler = new AchievementServiceHandler(getActivity());
        RestAdapter adapter = RetrofitNetworkService.makeAsyncRestAdapter();
        serviceHandler.retriveAchievement(adapter, 0, notifyHandler, LOAD_NEW_ACHIEVE_DATA);
    }

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        return;
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        currentFirstShowingItem = firstVisibleItem;
    }

    /**
     * Initialize the achievement list including
     * 1. Load the last achievement list in local storage
     * 2. Start the async loading to get the latest achievement data
     */
    private void initAchievementListDataset(){
        //TODO: load the last achievement list in local storage
        AchievementServiceHandler serviceHandler = new AchievementServiceHandler(getActivity());
        RestAdapter adapter = RetrofitNetworkService.makeAsyncRestAdapter();
        serviceHandler.retriveAchievement(adapter, 0, notifyHandler, INIT_ACHIEVE_DATA);
    }

    private static class NotifyHandler extends Handler {
        private WeakReference<ChampionAchievementTabFragment> mFragment;
        NotifyHandler(ChampionAchievementTabFragment fragment){
            mFragment = new WeakReference<ChampionAchievementTabFragment>(fragment);
        }

        public void setTarget(ChampionAchievementTabFragment fragment){
            if(null != fragment){
                mFragment.clear();
                mFragment = new WeakReference<ChampionAchievementTabFragment>(fragment);
            }
        }
        private List<ChampionAchievementFragmentAdapter.ChampionAchievementItem> extractListFromMessage(Message data){
            Bundle bundle = data.getData();
            Object[] ds = (Object[])bundle.get(RetrofitNetworkService.RESULT_DATA);
            List<ChampionAchievementFragmentAdapter.ChampionAchievementItem> items = new ArrayList<>(ds.length);
            for(Object o : ds){
                items.add((ChampionAchievementFragmentAdapter.ChampionAchievementItem)o);
            }
            return items;
        }

        @Override
        public void handleMessage(Message msg) {
            ChampionAchievementTabFragment fragment = mFragment.get();
            List<ChampionAchievementFragmentAdapter.ChampionAchievementItem> items;
            HeaderViewListAdapter headerAdapter;
            ChampionAchievementFragmentAdapter mAdapter;
            if(null != fragment){
                switch(msg.what){
                    case INIT_ACHIEVE_DATA:
                        items = extractListFromMessage(msg);
                        fragment.adapter = new ChampionAchievementFragmentAdapter(fragment.getActivity());
                        fragment.adapter.setDataset(items);
                        if(null != fragment.achievmentList){
                            fragment.achievmentList.setAdapter(fragment.adapter);
                        }
                        break;
                    case LOAD_NEW_ACHIEVE_DATA:
                        items = extractListFromMessage(msg);
                        headerAdapter =
                                (HeaderViewListAdapter)fragment.achievmentList.getAdapter();
                        mAdapter = (ChampionAchievementFragmentAdapter)headerAdapter.getWrappedAdapter();
                        mAdapter.insertDataset(items);
                        mAdapter.notifyDataSetChanged();
                        fragment.pullToRefreshLayout.setRefreshComplete();
                        break;
                    case LOAD_OLD_ACHIEVE_DATA:
                        items = extractListFromMessage(msg);
                        headerAdapter =
                                (HeaderViewListAdapter)fragment.achievmentList.getAdapter();
                        mAdapter = (ChampionAchievementFragmentAdapter)headerAdapter.getWrappedAdapter();
                        mAdapter.appendDataset(items);
                        mAdapter.notifyDataSetChanged();
                        fragment.achievmentList.onLoadMoreComplete();
                        break;
                    default:
                        break;
                }
            }
            super.handleMessage(msg);
        }
    }

    @Override
    public void onDestroy() {
        notifyHandler = null;
        super.onDestroy();
    }
}
